package ru.vba.builder;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import ru.vba.context.FieldContext;
import ru.vba.context.GameContext;
import ru.vba.context.impl.EruditContext;
import ru.vba.context.impl.EruditFieldContext;
import ru.vba.pojo.Bonus;
import ru.vba.pojo.Coordinate;
import ru.vba.pojo.Player;
import ru.vba.pojo.Point;
import ru.vba.strategy.GameStrategy;
import ru.vba.strategy.impl.GameStrategyImpl;

public class GameBuilder {
	private final static int DEFAULT_WIDTH = 8;
	private final static int DEFAULT_HEIGHT = 8;
	public static GameContext build(int count, Long timeout, String locale) throws Exception {
		List<Player> players = new ArrayList<Player>();
		for (int i = 0; i < count; i++){
			players.add(new Player());
		}
		try {
			FieldContext field = new EruditFieldContext(DEFAULT_WIDTH,DEFAULT_HEIGHT, getPoints(new Locale(locale)), getBonuses());

			GameContext context = new EruditContext(players, field);
			context.setTimeout(timeout);
			return context;
		} catch (IOException e) {
			throw new Exception(e);
		}

	}
	public static GameStrategy build() throws Exception{
		GameContext context = GameBuilder.build(4, 1L, "ru");
		GameStrategy str = new GameStrategyImpl(context);
		return str;
	}
	private static List<Point> getPoints(Locale locale) throws IOException{
		List<Point> result = new ArrayList<Point>();
        Properties props = loadPoints();
        Integer count = Integer.valueOf((String) props.get("count"));
        for (int i = 1; i <= count; i++){
        	Integer countPoint = Integer.valueOf(props.getProperty("count_" + i));
        	while(--countPoint>0){
            	Point point = new Point();
            	point.setId(new Long(i));
            	point.setScore(Integer.valueOf(props.getProperty("score_" + i)));
            	point.setValue(props.getProperty("point_" + i));
            	result.add(point);
        	}
        }
		return result;

	}
	private static Properties loadPoints() throws IOException {
		return loadProperties("points.properties");
	}
	private static Properties loadBonuses() throws IOException {
		return loadProperties("bonus.properties");
	}
	private static Properties loadProperties(String name) throws IOException {
		Properties props = new Properties();
        URL url = ClassLoader.getSystemResource(name);
        props.load(url.openStream());
		return props;
	}
	private static Map<Coordinate, Bonus> getBonuses() throws IOException{
		HashMap<Coordinate, Bonus> result = new HashMap<Coordinate, Bonus>();
		Properties props = loadBonuses();
		for (int i = 1; i <= DEFAULT_HEIGHT; i++){
			for (int k = 1; k <= DEFAULT_WIDTH; k++){
				Coordinate coordinate = new Coordinate();
				coordinate.setPosX(k);
				coordinate.setPosY(i);

				Bonus bonus = new Bonus();
				String f = (String) props.get("bonus_" + k + "_" + i);

				int factor = 1;
				if (f != null){
					factor = Integer.valueOf(f);
				}
				bonus.setFactor(factor);

				result.put(coordinate, bonus);
			}
		}
		return result;

	}
}
